//===============================================================================
// Microsoft Architecture Strategy Team
// LitwareHR - SaaS Sample Application
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================


using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shp.Runtime.Sitka.ServiceAgent.Managers;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
using Shp.Runtime.Sitka.ServiceAgent.Tests.Mocks;
using System.Threading;

using Shp.Runtime.Sitka.ServiceAgent.Factories;
using Shp.Runtime.Sitka.ServiceGateway.SitkaClient;

namespace Shp.Runtime.Sitka.ServiceAgent.Tests
{
    /// <summary>
    /// Summary description for RepositoryCacheFixture
    /// </summary>
    [TestClass]
    public class CacheManagerFixture
    {
        public CacheManagerFixture()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion


        [TestMethod]
        public void ShouldFailToRetrieveEntityFromDefaultCache()
        {
            using (RepositoryCacheManager cache = new RepositoryCacheManager(null))
            {
                MockExtendedEntity entity = new MockExtendedEntity(Guid.NewGuid(), "Tag 1");
                MockExtendedEntityMapper mapper = new MockExtendedEntityMapper();
                Entity f_e =  mapper.FromType( entity );

                cache.AddOrUpdateEntity("tenant1", f_e);

                Entity r_f_e = cache.GetEntityFrom("tenant1", f_e.Kind , f_e.Id);
                Assert.IsNull(r_f_e);
            }
        }

        [TestMethod]
        public void ShouldFailRetrieveEntityFromCache()
        {
            using (RepositoryCacheManager cache = new RepositoryCacheManager())
            {
                MockExtendedEntity entity = new MockExtendedEntity(Guid.NewGuid(), "Tag 1");
                MockExtendedEntityMapper mapper = new MockExtendedEntityMapper();

                Entity fe = mapper.FromType(entity);
                cache.AddOrUpdateEntity("tenant1", fe);

                Assert.AreEqual( fe.Id, (cache.GetEntityFrom("tenant1", typeof(MockExtendedEntity).ToString(), fe.Id) as Entity).Id );
            }
        }

        [TestMethod]
        public void ShouldRetrieveEntityFromDefaultCacheBuiltFromCacheFactory()
        {
            using (IRepositoryCacheManager cache = RepositoryCacheFactory.BuildManager() )
            {
                MockExtendedEntity entity = new MockExtendedEntity(Guid.NewGuid(), "Tag 1");
                MockExtendedEntityMapper mapper = new MockExtendedEntityMapper();

                Entity fe = mapper.FromType(entity);
                cache.AddOrUpdateEntity("tenant1", fe);

                Assert.AreEqual(fe.Id, (cache.GetEntityFrom("tenant1", typeof(MockExtendedEntity).ToString(), fe.Id) as Entity).Id);

            }
        }

        //[TestMethod]
        //public void ShouldRetrieveEntityFromDefaultCacheAndReturnNullAfterExpiration()
        //{
        //    using (RepositoryCacheManager cache = new RepositoryCacheManager("", new SlidingTime(TimeSpan.FromSeconds(3))))
        //    {
        //        MockExtendedClass entity = new MockExtendedClass(Guid.NewGuid(), "Tag 1");

        //        cache.AddOrUpdateEntity("tenant1", "MockExtendedClass", entity);

        //        MockExtendedClass r_entity = (MockExtendedClass)cache.GetEntityFrom("tenant1", "MockExtendedClass", entity.Id);

        //        Assert.AreEqual(entity.Id, r_entity.Id);
        //        Assert.AreEqual(entity.Tag, r_entity.Tag);
        //        Assert.IsTrue(r_entity.IsCached);

        //        Thread.Sleep(4000);

        //        r_entity = (MockExtendedClass)cache.GetEntityFrom("tenant1", "MockExtendedClass", entity.Id);

        //        Assert.IsNull(r_entity);
        //    }
        //}


        //[TestMethod]
        //public void ShouldRetrieveEntityFromDefaultCacheAndUpdate()
        //{
        //    using (RepositoryCacheManager cache = new RepositoryCacheManager("", new SlidingTime(TimeSpan.FromSeconds(3))))
        //    {
        //        MockExtendedClass entity = new MockExtendedClass(Guid.NewGuid(), "Tag 1");

        //        cache.AddOrUpdateEntity("tenant1", "MockExtendedClass", entity);

        //        MockExtendedClass r_entity = (MockExtendedClass)cache.GetEntityFrom("tenant1", "MockExtendedClass", entity.Id);

        //        Assert.AreEqual(entity.Id, r_entity.Id);
        //        Assert.AreEqual(entity.Tag, r_entity.Tag);
        //        Assert.IsTrue(r_entity.IsCached);

        //        entity.Tag = "Tag 2";
        //        cache.AddOrUpdateEntity("tenant1", "MockExtendedClass", entity);

        //        r_entity = (MockExtendedClass)cache.GetEntityFrom("tenant1", "MockExtendedClass", entity.Id);

        //        Assert.AreEqual(entity.Id, r_entity.Id);
        //        Assert.AreEqual(entity.Tag, r_entity.Tag);
        //        Assert.IsTrue(r_entity.IsCached);
        //    }
        //}

        //[TestMethod]
        //public void ShouldRetrieveCachedResultSetFromQuery()
        //{
        //    using (RepositoryCacheManager cache = new RepositoryCacheManager("", new SlidingTime(TimeSpan.FromSeconds(3))))
        //    {
        //        MockExtendedClass entity1 = new MockExtendedClass(Guid.NewGuid(), "Tag 1");
        //        MockExtendedClass entity2 = new MockExtendedClass(Guid.NewGuid(), "Tag 2");
        //        MockExtendedClass entity3 = new MockExtendedClass(Guid.NewGuid(), "Tag 3");

 

        //        cache.AddOrUpdateEntity("tenant1", "MockExtendedClass", entity);

        //        MockExtendedClass r_entity = (MockExtendedClass)cache.GetEntityFrom("tenant1", "MockExtendedClass", entity.Id);

        //        Assert.AreEqual(entity.Id, r_entity.Id);
        //        Assert.AreEqual(entity.Tag, r_entity.Tag);
        //        Assert.IsTrue(r_entity.IsCached);

        //        entity.Tag = "Tag 2";
        //        cache.AddOrUpdateEntity("tenant1", "MockExtendedClass", entity);

        //        r_entity = (MockExtendedClass)cache.GetEntityFrom("tenant1", "MockExtendedClass", entity.Id);

        //        Assert.AreEqual(entity.Id, r_entity.Id);
        //        Assert.AreEqual(entity.Tag, r_entity.Tag);
        //        Assert.IsTrue(r_entity.IsCached);
        //    }
        //}


    }
}
